#ifndef GAMEENGINE_GEOMETRY_VECTOR2D_H
#define GAMEENGINE_GEOMETRY_VECTOR2D_H

#include <GameEngine/Geometry/geometry_settings.h>

#include <GameEngine/Geometry/Location/point2d.h>



#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Class used to represent 2D vectors
/*!
 @note A 2D vector is made of two coordinates, typically
       named x and y. The coordinates are of type T,
	   which allows client code to choose the level of
	   precision (typically, T will be either float or
	   double)
 @todo Setup unit tests
 @sa The Vector3d class that handles 3D vectors, and the Point2d class that
     handles 2D points.
 */
template <class T>
class Vector2d : public Point2d<T> {

public:
	Vector2d();
	Vector2d(const T& x, const T& y);
	Vector2d(const Point2d<T>& origin, const Point2d<T>& destination);
	template <class R> Vector2d(const Point2d<R>& rhs);
	Vector2d(const Vector2d& rhs);
	virtual ~Vector2d();
	Vector2d& operator=(const Vector2d& rhs);

	Vector2d& operator+=(const Vector2d& rhs);
	Vector2d& operator-=(const Vector2d& rhs);
	Vector2d& operator*=(const Vector2d& rhs);
	Vector2d operator+(const Vector2d& rhs) const;
	Vector2d operator-(const Vector2d& rhs) const;
	Vector2d operator*(const Vector2d& rhs) const;

	template <class R> Vector2d& operator+=(const Vector2d<R>& rhs);
	template <class R> Vector2d& operator-=(const Vector2d<R>& rhs);
	template <class R> Vector2d& operator*=(const Vector2d<R>& rhs);
	template <class R> Vector2d operator+(const Vector2d<R>& rhs) const;
	template <class R> Vector2d operator-(const Vector2d<R>& rhs) const;
	template <class R> Vector2d operator*(const Vector2d<R>& rhs) const;

	template <class R> Vector2d& operator*=(const R& rhs);
	template <class R> Vector2d& operator/=(const R& rhs);

	template <class R> Vector2d operator*(const R& rhs) const;
	template <class R> Vector2d operator/(const R& rhs) const;
	template <class R, class T> friend Vector2d<T> operator*(const R& lhs, const Vector2d<T>& rhs);
	template <class R, class T> friend Vector2d<T> operator/(const R& lhs, const Vector2d<T>& rhs);

	static T dot(const Vector2d& v0, const Vector2d& v1);
	T dot(const Vector2d& rhs) const;

	static bool collinear(const Vector2d& v0, const Vector2d& v1, const T& tolerance = 0.000001);
	bool collinear(const Vector2d& rhs, const T& tolerance = 0.000001) const;

	Vector2d& normalize();
	Vector2d normalize() const;

	T square_length() const;
	T length() const;
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/Location/vector2d.hpp>

#endif
